home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / Documentation / Engineering Notes / Miscellaneous / Extensions Manager < prev    next >
Encoding:
Text File  |  1996-08-16  |  10.6 KB  |  161 lines  |  [TEXT/ttxt]

  1. OpenDoc
  2. Development
  3. Framework
  4.                                                                                                                                                                                      
  5. Extensions Manager
  6. ODF Release 1                                                                                                                                                             
  7.  
  8. Table of Contents
  9. -------------------
  10. • Overview
  11. • Enabling Extension Support
  12. • Accessing the Extension Manager
  13. • ODObject Extension API
  14. • Registering An Extension
  15. • Testing for an Extension
  16. • Acquiring an Extension
  17. • Releasing an Extension
  18. • Purging Extensions
  19. • Abandoning Extensions
  20. • Implementing Extensions
  21.  
  22.  
  23. Overview
  24.  
  25. The ODF FW_CExtensionManager class provides support for the registration, creation, and management of subclasses of ODExtension. This document describes the steps required to implement extension support in your part.
  26.  
  27.  
  28. Enabling Extension Support
  29.  
  30. Extension management can be enabled in an ODF part by editing its “Defines.k” file. In its default state, “Defines.k” contains the following line:
  31.  
  32.    #define FW_SUPPORTS_EXTENSIONS     0
  33.  
  34. To enable extension management, edit the line to read:
  35.  
  36.    #define FW_SUPPORTS_EXTENSIONS     1
  37.  
  38. Building a part with FW_SUPPORTS_EXTENSIONS defined as 1 causes ODF to automatically instantiate an instance of FW_CExtensionManager when your part is initialized.
  39.  
  40.  
  41. Accessing the Extension Manager
  42.  
  43. Your part’s extension manager can be accessed by calling the GetExtensionManager of FW_CPart as in the following function, SomeMethod, that takes an environment and a pointer to a part as parameters:
  44.  
  45.      void SomeMethod(Environment* ev, CMyPart* myPart)
  46.      {
  47.           FW_CExtensionManager* extMgr;
  48.           extMgr = myPart->GetExtensionManager(ev);
  49.      }
  50.  
  51.  
  52. ODObject Extension API
  53.  
  54. ODObject and derived classes have a small API for extension-related arbitration. The API consists of three methods: HasExtension, AcquireExtension, and ReleaseExtension. ODF provides support for this API at the part level. ODF does not provide support for this API for objects other than parts.
  55.  
  56.  
  57. Registering An Extension
  58.  
  59. Extensions supported by your part need to be registered with the extension manager. To register your extension, first obtain your part’s extension manager. Once you’ve obtained the extension manager, call the RegisterExtension method of the extension manager. The parameters passed to RegisterExtension are detailed below:
  60.  
  61.      void FW_CExtensionManager::RegisterExtension(Environment* ev, 
  62.                                             const char* name, 
  63.                                             CreateExtensionFunc createFunc,
  64.                                             void* refCon,
  65.                                             FW_Boolean cacheWhenReleased);
  66.  
  67. const char* name : extensions are acquired by name. This should be a pointer to a constant or to a string allocated in the heap that exists while your part is active. It should not be a pointer to a temporary object created on the stack.
  68.  
  69. CreateExtensionFunc createFunc : The address of the creation function to call when the extension is requested by name.  The creation function must be of the following type:
  70.  
  71.      typedef ODExtension* (*CreateExtensionFunc)(Environment* ev, 
  72.           FW_CPart* part, const char* name, void* refCon);
  73.  
  74. void* refCon : This parameter will be passed to the creation function registered for the extension. You can use this to store a value you need access to when creating your extension.
  75.  
  76. FW_Boolean cacheWhenRelease : When all clients of your extension have released the extension, the extension manager will either dispose the extension or cache it, depending on this value. If cacheWhenReleased is FALSE, the extension will be disposed when the last client releases the extension. The creation function will be called the next time the extension is acquired. If cacheWhenReleased is TRUE, the extension manager will keep the extension cached when the last client releases it.
  77.  
  78. Note:  When OpenDoc gets low on memory it calls the Purge method of active parts. When an ODF part’s Purge method is called, it purges cached extensions to free memory.  This means that your part cannot rely on caching to always keep an instance of a specific extension alive. If you require this behavior, you should explicitly acquire a reference to the extension to prevent its reference count from dropping to zero.
  79.  
  80.  
  81. Testing for an Extension
  82.  
  83. When OpenDoc or an OpenDoc object wants to test whether or not a part can provide a specific extension, it calls the object’s HasExtension method. When your part’s HasExtension method is called, the extension manager will return TRUE if the specified extension has been registered, and FALSE if it has not. 
  84.  
  85.  
  86. Acquiring an Extension
  87.  
  88. When OpenDoc or an OpenDoc object wants to acquire an extension, it calls the object’s AcquireExtension method. The ODObject API of AcquireExtension is as follows (this interface is defined by OpenDoc, not by ODF) :
  89.  
  90.      ODExtension ODObject::AcquireExtension(Environment* ev, const char* name);
  91.  
  92. The FW_CExtension implementation of this API is extended to include a third parameters as follows:
  93.  
  94.      ODExtension FW_CExtensionManager::AcquireExtension(Environment* ev, 
  95.           const char* name, 
  96.           FW_Boolean createIt);
  97.  
  98. When your part’s AcquireExtension method is called from outside of your part (i.e., by OpenDoc or another part), ODF automatically provides a createIt value of TRUE. At times, it may be necessary for your part to acquire one of its own extensions to get or set data owned by the extension. In this case, it makes sense to only acquire the extension if it already exists. Passing a createIt value of FALSE will acquire the extension if it exists, but will not allow it to be created if it does not.
  99.  
  100. When your part’s AcquireExtension method is called, the extension manager will do the following:
  101.  
  102. 1. If an extension of the specified name already exists, the extension’s Acquire method will be called to increment its reference count, and the extension will be returned to the caller. This applies to cached extensions as well as extensions that exist and have a reference count greater than zero. This mechanism insures that your part will provide one, and only one, instance of a specific extension regardless of the number of clients.
  103.  
  104. 2. If an extension of the specifed name does not exist, but the extension has been registered and the value of createIt is TRUE, the appropriate creation function will be called. The creation function is expected to create, initialize and return an instance of the specified extension. The extension manager returns the newly created extension to the caller.
  105.  
  106. 3. If the extension does not exist and either has not been registered or the value of createIt is FALSE, the AcquireExtension method your part inherited from its base class is called, and the result is returned.  In the current version of OpenDoc, calling ODPart::AcquireExtension causes an exception to be thrown, which is the correct behavior when an unsupported extension is acquired.
  107.  
  108.  
  109. Releasing an Extension
  110.  
  111. When a client of an extension is finished using the extension, it calls the Release method of the extension. Note the semantics: an extension is acquired from its base object, but is released directly. When the extension reference count drops to zero, the extension calls the ReleaseExtension method of its base object.
  112.  
  113. When your part’s ReleaseExtension method is called, the extension manager does the following:
  114.  
  115. 1. If the extension was created by the extension manager and should be cached when released, the extension manager caches the extension and returns.
  116.  
  117. 2. If the extension was created by the extension manager and should not be cached when released, the extension manager deletes the extension and returns.
  118.  
  119. 3. If the extension was not created by the extension manager, the ReleaseExtension method your part inherited from its base class is called. In the current version of OpenDoc, calling ODPart::ReleaseExtension causes an exception to be thrown, which is the correct behavior when an unknown extension is released.
  120.  
  121.  
  122. Purging Extensions
  123.  
  124. When OpenDoc gets low on memory, it calls the Purge method of active parts.  When an ODF part’s Purge method is called, ODF calls the PurgeCachedExtensions method of the FW_CExtensionManager associated with the part. PurgeCachedExtensions deletes all extensions cached by the extension manager.
  125.  
  126.  
  127. Abandoning Extensions
  128.  
  129. When a base object is deleted, it is the responsibility of the base object to call the BaseRemoved method of every extension the object has created. ODF implements this for parts by calling the AbandonExtensions method of FW_CExtensionsManager when the part’s ReleaseAll method is called. AbandonExtensions deletes all cached extensions and calls the BaseRemoved method of every existing extension that has a reference count greater than zero.
  130.  
  131.  
  132. Implementing Extensions
  133.  
  134. The OpenDoc extension protocol is slightly complex. The following guidelines provide useful information on the correct implementation of extensions. These tips are not specific to ODF.
  135.  
  136. Every method of an extension should call the IsValid method of the extension before referencing the extension’s base object. If IsValid returns FALSE, the extension should throw an error of type kODErrInvalidExtension. In ODF, this can be done as follows:
  137.  
  138.      FW_PlatformError error;
  139.      if (somSelf->IsValid(ev))
  140.      {
  141.         error = DoSomething(ev);
  142.      }
  143.      else
  144.         error = kODErrInvalidExtension;
  145.  
  146.     if (error != FW_xNoError)
  147.           FW_SetEvError(ev, error);
  148.  
  149. Every extension class must override Release and implement the following logic (this snippet is taken directly from the ODF Semantic Interface extension):
  150.  
  151.      FW_Boolean isValid = somSelf->IsValid(ev);
  152.      FW_OSemanticInterface_parent_ODSemanticInterface_Release(somSelf,ev);
  153.         
  154.      if (!isValid && somSelf->GetRefCount(ev) == 0)
  155.           delete somSelf;
  156.  
  157. The extension MUST test IsValid before calling the inherited Release method. This is necessary because Release will decrement the reference count of the extension and, if the reference count drops to zero, will call the ReleaseExtension method of the base object. The base object may delete the extension when ReleaseExtension is called. It is not safe to call the IsValid method of the extension after it has been deleted.  If IsValid is FALSE, the base object has been removed. If the base has been removed, and the reference count dropped to zero when the inherited Release method was called, the extension must delete itself. If the extension does not delete itself, a memory leak will result. 
  158.  
  159.  
  160. © 1993 - 1996 Apple Computer, Inc. All rights reserved.
  161. Apple, the Apple Logo, Macintosh, and OpenDoc are trademarks of Apple Computer, Inc., registered in the United States and other countries.